﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ProtobufTools
{
    public static class ObjectExtensions
    {
        public static void InitSelf(this object o)
        {
            Type t = o.GetType();

            if (t != typeof(object))
            {
                foreach (PropertyInfo info in t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    if (info.CanWrite)
                    {
                        if (info.PropertyType == typeof(string))
                            info.SetValue(o, "", null);
                        else if (info.PropertyType == typeof(int))
                            info.SetValue(o, 0, null);
                        else if (info.PropertyType == typeof(float)
                            || info.PropertyType == typeof(double))
                            info.SetValue(o, 0.0f, null);
                        else if (info.PropertyType == typeof(decimal))
                            info.SetValue(o, 0m, null);
                        else if (info.PropertyType == typeof(DateTime))
                            info.SetValue(o, DateTime.Now, null);
                        else if (info.PropertyType == typeof(bool))
                            info.SetValue(o, false, null);
                        else
                        {
                            ConstructorInfo[] ciList = info.PropertyType.GetConstructors();
                            foreach (ConstructorInfo ci in ciList)
                            {
                                if (ci.GetParameters().Count() == 0)
                                {
                                    object propertyObj = ci.Invoke(null);
                                    propertyObj.InitSelf();

                                    try
                                    {
                                        info.SetValue(o, propertyObj, null);
                                    }
                                    catch (TargetParameterCountException)
                                    {
                                        if (t.Name == "List`1")
                                        {
                                            MethodInfo mi = t.GetMethod("Add");
                                            mi.Invoke(o, new object[] { propertyObj });
                                        }                                        
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
